/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/

// https://www.bouncycastle.org/download/bcprov-jdk15on-150.jar
// https://www.bouncycastle.org/download/bcpkix-jdk15on-150.jar

package csrgenerate;

//import java.io.ByteArrayOutputStream;
//import java.io.PrintStream;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.SecureRandom;
//import java.security.Signature;
import javax.security.auth.x500.X500Principal;
import org.bouncycastle.operator.ContentSigner;
import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
import org.bouncycastle.pkcs.PKCS10CertificationRequest;
//import sun.security.pkcs.PKCS10;
//import sun.security.x509.X500Name;

import org.bouncycastle.asn1.x500.X500Name;
import javax.security.auth.x500.X500Principal;
//import javax.security.auth.
//import sun.security.x509.X500Signer;

// http://www.bouncycastle.org/latest_releases.html
import org.bouncycastle.pkcs.PKCS10CertificationRequestBuilder;
import org.bouncycastle.pkcs.jcajce.JcaPKCS10CertificationRequestBuilder;
import org.bouncycastle.util.encoders.Base64Encoder;
import sun.misc.BASE64Encoder;

/**
 *
 * @author rmartinezch
 */
public class CsrGenerate {
    
    private static PublicKey publicKey = null;
    private static PrivateKey privateKey = null;
    private static KeyPairGenerator keyGen = null;
    private static CsrGenerate gcsr = null;
    
    private CsrGenerate() {
        try {
            keyGen = KeyPairGenerator.getInstance("RSA");
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        keyGen.initialize(2048, new SecureRandom());
        KeyPair keypair = keyGen.generateKeyPair();
        publicKey = keypair.getPublic();
        privateKey = keypair.getPrivate();
        if (publicKey != null){System.out.println("pub key ok");}
        if (privateKey != null){System.out.println("pri key ok");}
    }
    
    public static CsrGenerate getInstance() {
        if (gcsr == null)
            gcsr = new CsrGenerate();
        return gcsr;
    }
    
    public String getCSR(String cn) throws Exception {
        byte[] csr = generatePKCS10(cn, "Java", "JournalDev", "Cupertino",
                "California", "USA");
        return new String(csr);
    }
    
    /**
     *
     * @param CN
     *            Common Name, is X.509 speak for the name that distinguishes
     *            the Certificate best, and ties it to your Organization
     * @param OU
     *            Organizational unit
     * @param O
     *            Organization NAME
     * @param L
     *            Location
     * @param S
     *            State
     * @param C
     *            Country
     * @return
     * @throws Exception
     */
    private static byte[] generatePKCS10(String CN, String OU, String O,
            String L, String S, String C) throws Exception {
        // generate PKCS10 certificate request
        
        // select algorithm
        String sigAlg = "MD5WithRSA";
        // csr builder
        //PKCS10 pkcs10 = new PKCS10(publicKey);
        // algortihm & key to signer
//        Signature signature = Signature.getInstance(sigAlg);
  //      signature.initSign(privateKey);
        // common, orgUnit, org, locality, state, country
        X500Name x500Name = new X500Name("cn=test,o=gina");//CN, OU, O, L, S, C);
//        X500Principal x500Principal = new X500Principal(CN);
        // build csr file
//        pkcs10.encodeAndSign(new X500Signer(signature, x500Name));
        // another solution
        PKCS10CertificationRequestBuilder p10Builder;
        p10Builder = new JcaPKCS10CertificationRequestBuilder( x500Name, publicKey);
        JcaContentSignerBuilder csBuilder = new JcaContentSignerBuilder("MD5WithRSA");
        ContentSigner signer = csBuilder.build(privateKey);
        PKCS10CertificationRequest csr = p10Builder.build(signer);
        // here, csr is created, then, make it printable
        return csr.toString().getBytes();
        /*
        ByteArrayOutputStream bs = new ByteArrayOutputStream();
        PrintStream ps = new PrintStream(bs);
        pkcs10.print(ps);
        byte[] c = bs.toByteArray();
        try {
            if (ps != null)
                ps.close();
            if (bs != null)
                bs.close();
        } catch (Throwable th) {
        }
        return c;
                */
    }
    
    public PublicKey getPublicKey() {
        return publicKey;
    }
    
    public PrivateKey getPrivateKey() {
        return privateKey;
    }
    
    public static void main(String[] args) throws Exception {
        CsrGenerate gcsr = CsrGenerate.getInstance();
        
        System.out.println("Public Key:\n"+gcsr.getPublicKey().toString());
        
        BASE64Encoder encoder = new BASE64Encoder();
        System.out.println("Private Key:\n"+ encoder.encode(gcsr.getPrivateKey().getEncoded()));
        
        
        
        String csr = gcsr.getCSR("journaldev.com <http://www.journaldev.com>");
        System.out.println("CSR Request Generated!!");
        System.out.println(csr);
    }
    
    
}
